///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#ifndef __ControllerManager_H__
#define __ControllerManager_H__

#include "OgrePrerequisites.h"

#include "OgreCommon.h"
#include "OgreSingleton.h"
#include "OgreController.h"
#include "OgrePredefinedControllers.h"
#include "OgreTextureUnitState.h"
#include "OgreSharedPtr.h"

namespace Ogre {
	
	

    typedef SharedPtr< ControllerValue<Real> > ControllerValueRealPtr;
    typedef SharedPtr< ControllerFunction<Real> > ControllerFunctionRealPtr;

    
    class _OgreExport ControllerManager : public Singleton<ControllerManager>, public MemAlloc_General
    {
    protected:
        typedef set<Controller<Real>*>::type ControllerList;
        ControllerList mControllers;

        /// Global predefined controller
        ControllerValueRealPtr mFrameTimeController;
        
		/// Global predefined controller
		ControllerFunctionRealPtr mPassthroughFunction;

		// Last frame number updated
        unsigned long mLastFrameNumber;

    public:
        ControllerManager();
        ~ControllerManager();

        
        Controller<Real>* createController(const ControllerValueRealPtr& src,
            const ControllerValueRealPtr& dest, const ControllerFunctionRealPtr& func);

        
        Controller<Real>* createFrameTimePassthroughController(
            const ControllerValueRealPtr& dest);

        
        void clearControllers(void);

        
        void updateAllControllers(void);


        
        const ControllerValueRealPtr& getFrameTimeSource(void) const;

		
		const ControllerFunctionRealPtr& getPassthroughControllerFunction(void) const;

        
        Controller<Real>* createTextureAnimator(TextureUnitState* layer, Real sequenceTime);

		
        Controller<Real>* createTextureUVScroller(TextureUnitState* layer, Real speed);

        
        Controller<Real>* createTextureUScroller(TextureUnitState* layer, Real uSpeed);

		
        Controller<Real>* createTextureVScroller(TextureUnitState* layer, Real vSpeed);

        
        Controller<Real>* createTextureRotater(TextureUnitState* layer, Real speed);

        
        Controller<Real>* createTextureWaveTransformer(TextureUnitState* layer, TextureUnitState::TextureTransformType ttype,
            WaveformType waveType, Real base = 0, Real frequency = 1, Real phase = 0, Real amplitude = 1);

        
        Controller<Real>* createGpuProgramTimerParam(GpuProgramParametersSharedPtr params, size_t paramIndex,
            Real timeFactor = 1.0f);

        
        void destroyController(Controller<Real>* controller);

		
		Real getTimeFactor(void) const;

		
		void setTimeFactor(Real tf);

		
		Real getFrameDelay(void) const;

		
		void setFrameDelay(Real fd);

		
        Real getElapsedTime(void) const;

        
        void setElapsedTime(Real elapsedTime);

        
        static ControllerManager& getSingleton(void);
        
        static ControllerManager* getSingletonPtr(void);
    };

	
	

}
#endif
